package com.upeoe.shiro.chapter1;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.util.ThreadContext;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;

/**
 * @author ven_hxz
 * @create 2016-07-03 上午9:53
 */
public class AuthenticatorTutorial {

    @Test
    public void testAllSuccessfulStrategyWithSuccess() {
        login("classpath:shiro-authenticator-all-success.ini");

        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        Assert.assertEquals(2, principals.asList().size());
    }

    @Test(expected = UnknownAccountException.class)
    public void testAllSuccessStrategyWithFail() {
        login("classpath:shiro-authenticator-all-fail.ini");
    }

    @Test
    public void testAtLeastOneSuccessfulStrategyWithSuccess() {
        login("classpath:shiro-authenticator-atLeastOne-success.ini");

        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        Assert.assertEquals(2, principals.asList().size());
    }

    @Test
    public void testFirstSuccessfulStrategyWithSuccess() {
        login("classpath:shiro-authenticator-first-success.ini");

        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        Assert.assertEquals(1, principals.asList().size());
    }

    @Test
    public void testAtLeastTwoSuccessfulStrategyWithSuccess() {
        login("classpath:shiro-authenticator-atLeastTwo-success.ini");

        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        Assert.assertEquals(2, principals.asList().size());
    }

    @Test
    public void testOnlyOneSuccessfulStrategyWithSuccess() {
        login("classpath:shiro-authenticator-onlyOne-success.ini");

        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        Assert.assertEquals(1, principals.asList().size());
    }

    private void login(String configFile) {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory(configFile);
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);

        Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("root", "root");
        currentUser.login(token);
    }

    @After
    public void tearDown() {
        ThreadContext.unbindSubject();
    }
}
